/*******************************************************************************
 Copyright (c) 2010 Koninklijke Philips N.V.,
 All Rights Reserved.
 
 File name: swtimer.c
 Description: Source file for the SWTIMER component, and provide the utility 
			  functions for the use of timers in the system.
 Project: XXX
 Component name: SWTIMER 
 $LastChangedDate:  $
 $Revision:  $
 $Author:  $
 Lighting GBU CFLi
 
 This source code and any compilation or derivative thereof is the
 proprietary information of Koninklijke Philips N.V.
 and is confidential in nature.
 Under no circumstances is this software to be combined with any Open Source
 Software in any way or placed under an Open Source License of any type without
 the express written permission of Koninklijke Philips N.V.
*******************************************************************************/

/****************************************************************************************
* INCLUDE FILES
****************************************************************************************/
#include "swtimer.h"

/****************************************************************************************
* LOCAL CONSTANTS
****************************************************************************************/
#define TMR_RESERVED        (1)
#define TMR_ACTIVE          (2)
#define TMR_ONCE		    (4)

#define TIMER_FREE          (0)
#define TIMER_STOP          (TMR_RESERVED)
#define TIMER_ACTIVE_ONCE   (TMR_RESERVED | TMR_ACTIVE | TMR_ONCE)
#define TIMER_ACTIVE_PERIOD (TMR_RESERVED | TMR_ACTIVE )



/****************************************************************************************
* LOCAL TYPEDEFS
****************************************************************************************/
typedef struct _swtimer_t
{
    uint8  state;
    uint16 timeout;
    uint16 interval;
    uint8  event;
    uint8  module_id;
} swtimer_t;



/****************************************************************************************
* LOCAL VARIABLES
****************************************************************************************/
static swtimer_t __swtimer[SWTIMER_NUMBER];
static uint8 __swtimer_initialized = FALSE;


/****************************************************************************************
* GLOBAL VARIABLES
****************************************************************************************/

/****************************************************************************************
* LOCAL FUNCTIONS PROTOTYPE
****************************************************************************************/

/****************************************************************************************
* LOCAL MACRO
****************************************************************************************/

#define SEND_ALARM(swtimer_id)                                   \
    queue_add_swtimer_event( __swtimer[swtimer_id].event,        \
                             0,                                  \
                             __swtimer[swtimer_id].module_id)

/****************************************************************************************
* GLOBAL FUNCTIONS
****************************************************************************************/

/*******************************************************************************
* Function:	
*                   swtimer_init
* Parameters:	
*                   void
* Returen:
*                   void
* Description: 
*                   software timer inialization.
*******************************************************************************/

void swtimer_init(void)
{
    uint8 count;
	
	count = SWTIMER_NUMBER;
	
    while (count)
    {
        count--;
        __swtimer[count].state = TIMER_FREE;
    }

    __swtimer_initialized = TRUE;
}

/*******************************************************************************
* Function:	
*                   swtimer_create
* Parameters:	
*                   event [IN], when the sw timer time out, the event will be generated.
*					module_id [IN], which module create the swtimer.
* Returen:
*                   the created swtimer id.
* Description: 
*                   Create software timer, it will be called by other module, which will
*                   will use the software timer.
*******************************************************************************/

uint8 swtimer_create(uint8 event,  uint8 module_id)
{
    uint8 count = SWTIMER_NUMBER;
    uint8 timer_id = SWTIMER_ID_INIT;

    /* Searching free timer */
    while (count)
    {
        count--;
        if (__swtimer[count].state == TIMER_FREE)
        {
            timer_id = count;
            break;
        }
    }

    if (timer_id != SWTIMER_ID_INIT)
    {
        __swtimer[timer_id].module_id = module_id; 
        __swtimer[timer_id].event = event;
        __swtimer[timer_id].state = TIMER_STOP;
    }

    return timer_id;
} 

/*******************************************************************************
* Function:	
*                   swtimer_destroy
* Parameters:	
*                   swtimer_id [IN], the sw timer id will be destroyed.
* Returen:
*                   void.
* Description: 
*                   Destroy a software timer.
*******************************************************************************/

void swtimer_destroy( uint8 swtimer_id )
{
    __swtimer[swtimer_id].state = TIMER_FREE;
}

/*******************************************************************************
* Function:	
*                   swtimer_start
* Parameters:	
*                   swtimer_id [IN], the sw timer id.
*                   interval_ms [IN], the sw timer interval, the unit is ms.
*                   state [IN], the state of the sw timer, it can be set to active once or ative period.
* Returen:
*                   void.
* Description: 
*                   Start a software timer.
*******************************************************************************/

void swtimer_start( uint8 swtimer_id, uint16 interval_ms, uint8 state)
{
    __swtimer[swtimer_id].state =  state;       
    __swtimer[swtimer_id].interval   = interval_ms;
    __swtimer[swtimer_id].timeout    = interval_ms / SWTIMER_INTERVAL;
}

void swtimer_start_once( uint8 swtimer_id, uint16 interval_ms )
{
    swtimer_start(swtimer_id, interval_ms, TIMER_ACTIVE_ONCE);
}

void swtimer_start_period( uint8 swtimer_id, uint16 interval_ms )
{
    swtimer_start(swtimer_id, interval_ms, TIMER_ACTIVE_PERIOD);
}

/*******************************************************************************
* Function:	
*                   swtimer_stop
* Parameters:	
*                   swtimer_id [IN], the sw timer id will be destroyed.
* Returen:
*                   void.
* Description: 
*                   Stop a software timer.
*******************************************************************************/

void swtimer_stop(uint8 swtimer_id)
{
    __swtimer[swtimer_id].state = TIMER_STOP;
}


/*******************************************************************************
* Function:	
*                   swtimer_is_runnig
* Parameters:	
*                   swtimer_id [IN], the sw timer id will be destroyed.
* Returen:
*                   TRUE/FALSE.
* Description: 
*                   Check a software timer is running or not.
*******************************************************************************/

uint8 swtimer_is_runnig(uint8 swtimer_id)
{
    if (__swtimer[swtimer_id].state != TIMER_STOP)
        return TRUE;
    else
        return FALSE;
}

/*******************************************************************************
* Function:	
*                   swtimer_drive_swtimer
* Parameters:	
*                   void.
* Returen:
*                   void.
* Description: 
*                   Hardware timer interval is generated, and it drive the sw timer.
*******************************************************************************/

void swtimer_drive_swtimer(void) 
{
    uint8 count = SWTIMER_NUMBER;

    if (!__timer_initialized)
        return;

    while (count)
    {
        count--;

        if (__swtimer[count].state & TMR_ACTIVE)
        {
            if (__swtimer[count].timeout == 0)
            {
                // ALARM!!!!
                SEND_ALARM(count);
                if (__swtimer[count].state & TMR_ONCE)
                {
                    __swtimer[count].state = TIMER_STOP;
                }
                else
                {   // Recharge
                    __swtimer[count].timeout = __swtimer[count].interval / SWTIMER_INTERVAL;
                }
            }
            else
            {
                __swtimer[count].timeout--;
            }
        }
    }
} 

/****************************************************************************************
* LOCAL FUNCTIONS
****************************************************************************************/

/***************************************************************************************/
